eval_ context

DOORS 9.5.2.1.

Don't deal with eval_ much, but I was under the impression that if I wanted it to have a certain Folder/Module/Object context I was going to have to send the eval_ code specifics about that context; such as folder name, module name (which it get the handle for), and object identifier.  I also played with sending it addr_ of int addr_ (copying something MM wrote) which worked.

To my surprise, the eval_ context was the same as the callers (such as current Object) and I didn't have to send it anything.  What am I missing?

-Louie


llandale - Mon Aug 10 15:42:00 EDT 2015

Re: eval_ context
Wolfgang Uhr - Tue Aug 11 02:21:43 EDT 2015

Hi Louie

There is nothing to miss. Yes, you have the same current object and so on. The advantage of eval_ is the possibility to deallocate Variables or to deallocate some strings. For example I have a script which loads some modules, performs some operations and crashes before it is finished. If you place your loop in the main script and the operations inside the eval_-Code, then the script can finish properly.

If doors would have had a acceptable garbage collection there would be any need for eval_

Best regards

Wolfgang

Re: eval_ context
Mathias Mamsch - Tue Aug 11 04:38:46 EDT 2015

Regarding "current" (Object Module), etc. I was never sure - as far as I know these are references, that are bound to a global DXL context variable and therefore shared by all DXL contexts. Therefore there is no need to pass "current" to an eval_ context. Changing the current module will change the current object?

Still I think relying on "current" inside an eval context is the same as relying on current inside a function. You should not do it.

There are also the interpreter flags (XFLAGS?) that are not bound to a specific DXL context or other parser settings (pragma encoding).

I think it is a good question, what information is actually part of a DXL context and what not. For example the stack size. Does the eval context share the stack size of its parent context, or even reuse the parent stack? Is it possible to have a different runLim inside an eval context than inside the parent context? Are they inherited by default? 

Feel free to post more results on that, if you have some time experimenting on that.

Regards, Mathias
 

Re: eval_ context
Wolfgang Uhr - Tue Aug 11 07:15:51 EDT 2015

Mathias Mamsch - Tue Aug 11 04:38:46 EDT 2015

Regarding "current" (Object Module), etc. I was never sure - as far as I know these are references, that are bound to a global DXL context variable and therefore shared by all DXL contexts. Therefore there is no need to pass "current" to an eval_ context. Changing the current module will change the current object?

Still I think relying on "current" inside an eval context is the same as relying on current inside a function. You should not do it.

There are also the interpreter flags (XFLAGS?) that are not bound to a specific DXL context or other parser settings (pragma encoding).

I think it is a good question, what information is actually part of a DXL context and what not. For example the stack size. Does the eval context share the stack size of its parent context, or even reuse the parent stack? Is it possible to have a different runLim inside an eval context than inside the parent context? Are they inherited by default? 

Feel free to post more results on that, if you have some time experimenting on that.

Regards, Mathias
 

> Feel free to post more results on that, if you have some time experimenting on that.

Hi Mathias

I thinkt the most important point at all is to change to the 64 bit doors before continuing whith such experiments. My fear is: To much will change.

Best regards

Wolfgang

 

Re: eval_ context
llandale - Tue Aug 11 13:33:51 EDT 2015

Mathias Mamsch - Tue Aug 11 04:38:46 EDT 2015

Regarding "current" (Object Module), etc. I was never sure - as far as I know these are references, that are bound to a global DXL context variable and therefore shared by all DXL contexts. Therefore there is no need to pass "current" to an eval_ context. Changing the current module will change the current object?

Still I think relying on "current" inside an eval context is the same as relying on current inside a function. You should not do it.

There are also the interpreter flags (XFLAGS?) that are not bound to a specific DXL context or other parser settings (pragma encoding).

I think it is a good question, what information is actually part of a DXL context and what not. For example the stack size. Does the eval context share the stack size of its parent context, or even reuse the parent stack? Is it possible to have a different runLim inside an eval context than inside the parent context? Are they inherited by default? 

Feel free to post more results on that, if you have some time experimenting on that.

Regards, Mathias
 

I'm trying to decide at run time which revision of which script to run so a simple "#include" statement won't work.  I figure to determine the actual file, insert it into an "#include" statement, and send that to eval_.  A script may care what the current object is and I want to make sure eval_ knows what that is.  But I guess it all works simply.  Thanks.

-Louie

Re: eval_ context
Wolfgang Uhr - Wed Aug 12 02:07:03 EDT 2015

llandale - Tue Aug 11 13:33:51 EDT 2015

I'm trying to decide at run time which revision of which script to run so a simple "#include" statement won't work.  I figure to determine the actual file, insert it into an "#include" statement, and send that to eval_.  A script may care what the current object is and I want to make sure eval_ knows what that is.  But I guess it all works simply.  Thanks.

-Louie

Hi Louie

> I'm trying to decide at run time which revision of which script to run so a simple "#include" statement won't work.

Try the following code ...

int demo1(string sMessage) {
print "Demo1." sMessage "\n";
return(1);
}

int demo2(string sMessage) {
print "Demo2." sMessage "\n";
return(2);
}

// ------------------------------

struct DemoDelegate {};

DemoDelegate initDelegate(int function(string)) {
int iPointer = addr_(function);
DxlObject dxlDelegate = new();
dxlDelegate->"iPointer" = iPointer;
return (addr_ dxlDelegate) DemoDelegate;
}

void redefineDelegateTarget(DemoDelegate delegate, int function(string)) {
DxlObject dxlDelegate = (addr_(delegate)) DxlObject;
int iPointer = addr_(function);
dxlDelegate->"iPointer" = iPointer;
}

int callDelegate(DemoDelegate delegate, string sMessage) {
int callDelegate_(int function(string), string sMessage) {
return(function(sMessage));
}
DxlObject dxlDelegate = (addr_(delegate)) DxlObject;
int iPointer = (dxlDelegate->"iPointer") int;
return(callDelegate_ (addr_(iPointer), sMessage));
}

// ------------------------------

DemoDelegate demoDelegate = initDelegate(demo1);

print callDelegate(demoDelegate, "X1");

redefineDelegateTarget(demoDelegate, demo2);

print callDelegate(demoDelegate, "X2");

Best regards

Wolfgang

Re: eval_ context
Mathias Mamsch - Wed Aug 12 11:16:10 EDT 2015

Wolfgang Uhr - Wed Aug 12 02:07:03 EDT 2015

Hi Louie

> I'm trying to decide at run time which revision of which script to run so a simple "#include" statement won't work.

Try the following code ...

int demo1(string sMessage) {
print "Demo1." sMessage "\n";
return(1);
}

int demo2(string sMessage) {
print "Demo2." sMessage "\n";
return(2);
}

// ------------------------------

struct DemoDelegate {};

DemoDelegate initDelegate(int function(string)) {
int iPointer = addr_(function);
DxlObject dxlDelegate = new();
dxlDelegate->"iPointer" = iPointer;
return (addr_ dxlDelegate) DemoDelegate;
}

void redefineDelegateTarget(DemoDelegate delegate, int function(string)) {
DxlObject dxlDelegate = (addr_(delegate)) DxlObject;
int iPointer = addr_(function);
dxlDelegate->"iPointer" = iPointer;
}

int callDelegate(DemoDelegate delegate, string sMessage) {
int callDelegate_(int function(string), string sMessage) {
return(function(sMessage));
}
DxlObject dxlDelegate = (addr_(delegate)) DxlObject;
int iPointer = (dxlDelegate->"iPointer") int;
return(callDelegate_ (addr_(iPointer), sMessage));
}

// ------------------------------

DemoDelegate demoDelegate = initDelegate(demo1);

print callDelegate(demoDelegate, "X1");

redefineDelegateTarget(demoDelegate, demo2);

print callDelegate(demoDelegate, "X2");

Best regards

Wolfgang

I think what you are trying to say, is that you can also incorporate the functionality of different revisions in different functions and call the right function at runtime. You do not necessary involve complex 'addr_' vodoo for that.

void func_rev1 () {
    ...
}

void func_rev2() {
    ...
}

void func(int rev) {
        if (rev == 1) func_rev1()
        if (rev == 2) func_rev2()
}

which is basically the same as you example with "hardcoded" function pointers. Anyway I do not think that approach fits to Louies requirement. I figure that he generally wants to version ANY dxl script and call the right version of the script under certain circumstances (e.g. baseline). In that case you cannot use 'virtual functions'.

Regards, Mathias

Re: eval_ context
llandale - Wed Aug 12 17:35:28 EDT 2015

Mathias Mamsch - Wed Aug 12 11:16:10 EDT 2015

I think what you are trying to say, is that you can also incorporate the functionality of different revisions in different functions and call the right function at runtime. You do not necessary involve complex 'addr_' vodoo for that.

void func_rev1 () {
    ...
}

void func_rev2() {
    ...
}

void func(int rev) {
        if (rev == 1) func_rev1()
        if (rev == 2) func_rev2()
}

which is basically the same as you example with "hardcoded" function pointers. Anyway I do not think that approach fits to Louies requirement. I figure that he generally wants to version ANY dxl script and call the right version of the script under certain circumstances (e.g. baseline). In that case you cannot use 'virtual functions'.

Regards, Mathias

No, different revisions of different files.  If there was only one file I could issue a straight #include, but now I figure I need to find the right file and issue the #include inside an eval_.  That's easy so long as the eval_ has the exact context as the calling program, which it appears it does.  Before I posted I was trying to send the addr_ int addr_ whatever of the "Folder", "Module", and "Object" and have the eval_ code establish context with "current = " statements.

Below, not shown is fAddins_FindFile() which a relative file vis-a-vis the "addins" environment variable (or "projectaddins"), but also knows to allow matches when the actual file has a revision marking "_r001" at the end of the name.

Thanks for the help.

I notice the below allows for these files to execute in program context.  Issuing an $include inside a function disallows that included file from having "global" declarations but running it in eval_ allows for that.


//***************************************************
string fRunEval_File(string in_NameFile_Dxl)
{ // Run the named DXL file.
 // eval_ is used, error is returned
 // If the file is not fully qualified then normal #include file resolution is used

  string DxlCode = "// fRunEval_File() code:
  #include <" in_NameFile_Dxl ">
  // end fRunEval_File() code"
  string ret = eval_(DxlCode)
  // print ret
 return(ret)
} // end fRunEval_File()


string fRunEval_Rev(string in_NameFile_Rev, int in_Addins_Type)
{ // Run the relative file.  Reved versions are allowed as per "fAddins_FindFile()".
 // Look for the relative file in the specified Addins directory

  string NameFile = fAddins_FindFile(in_NameFile_Rev, in_Addins_Type)
  if (null NameFile) //
  then ret = "Cannot find reved file [" in_NameFile_Rev "]"
  else ret = fRunEval_File(NameFile)

 return(ret)
} // end fRunEval_Rev()
-Louie